<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <!-- import CSS -->
  <link rel="stylesheet" href="css/element-ui/lib/theme-chalk/index.css">
</head>

<style>
  body {
    font-family: 'pingfang SC', 'helvetica neue', arial, 'hiragino sans gb', 'microsoft yahei ui', 'microsoft yahei', simsun, sans-serif;
  }

  .el-header {
    background-color: #409EFF;
    color: #333;
    text-align: center;
    line-height: 60px;
  }

  .el-footer {
    background-color: rgb(244, 244, 245);
    color: #333;
    text-align: center;
    line-height: 60px;
  }

  .el-aside {
    background-color: #D3DCE6;
    color: #333;
    text-align: center;
    line-height: 200px;
  }

  .el-main {
    background-color: #E9EEF3;
    color: #333;
    text-align: center;
    line-height: 40px;
  }

  #app>.el-container {
    height: 100%;
  }

  html,
  body,
  #app {
    height: 100%;
    padding: 0px;
    margin: 0px;
    overflow: hidden;
  }


  .chat-main {
    line-height: initial;
    text-align: left;
  }

  .chat-sender {
    clear: both;
    font-size: 80%;
  }

  .chat-sender div:nth-of-type(1) {
    float: left;
  }

  .chat-sender div:nth-of-type(2) {
    margin: 0 50px 2px 50px;
    padding: 0px;
    color: #848484;
    font-size: 70%;
    text-align: left;
  }

  .chat-sender div:nth-of-type(3) {
    background-color: white;
    float: left;
    margin: 0 20px 10px 20px;
    padding: 10px 10px 10px 10px;
    border-radius: 4px;
    text-indent: -5px;
    max-width: 500px;
  }

  .chat-receiver {
    clear: both;
    font-size: 80%;
  }

  .chat-receiver div:nth-of-type(1) {
    float: right;
  }

  .chat-receiver div:nth-of-type(2) {
    margin: 0px 50px 2px 50px;
    padding: 0px;
    color: #848484;
    font-size: 70%;
    text-align: right;
  }

  .chat-receiver div:nth-of-type(3) {
    float: right;
    background-color: #b2e281;
    margin: 0px 20px 10px 20px;
    padding: 10px 10px 10px 10px;
    border-radius: 4px;
    text-indent: 5px;
    max-width: 500px;
  }

  .chat-receiver div:first-child img,
  .chat-sender div:first-child img {
    width: 40px;
    height: 40px;
    /*border-radius: 10%;*/
  }

  .chat-left_triangle {
    height: 0px;
    width: 0px;
    border-width: 6px;
    border-style: solid;
    border-color: transparent white transparent transparent;
    position: relative;
    left: -22px;
    top: 3px;
  }

  .chat-right_triangle {
    height: 0px;
    width: 0px;
    border-width: 6px;
    border-style: solid;
    border-color: transparent transparent transparent #b2e281;
    position: relative;
    right: -22px;
    top: 3px;
  }

  .chat-notice {
    clear: both;
    font-size: 70%;
    color: white;
    text-align: center;
    margin-top: 15px;
    margin-bottom: 15px;
  }

  .chat-notice span {
    background-color: #cecece;
    line-height: 25px;
    border-radius: 5px;
    padding: 5px 10px;
  }

  .emojiList {
    display: flex;
    flex-wrap: wrap;
    padding: 5px;
  }

  .emojiItem {
    width: 10%;
    font-size: 30px;
    text-align: center;
    cursor: pointer;
    margin: 4px;
  }

  .chat-main li {
    overflow: auto;
  }

  .messageText {
    word-wrap: break-word;
  }

  .success-row {
    background: #f0f9eb;
  }
</style>

<body>
  <div id="app">
    <el-container>
      <el-header>
        <div>
          <span style="color: white;">{{teahouseName}}</span>
        </div>
      </el-header>
      <el-container>
        <el-aside width="200px" height="60px" :cell-style="{padding: '8px'}">
          <el-container style="height: 100%;">
            <el-main style="padding: 0px;height: 0;">
              <template>
                <el-scrollbar>
                  <li v-for="chat in chatGroup" @click="selectToChat(chat)" style="padding-top: 15px;">
                    <el-row height="100" :gutter="20">
                      <el-col :span="8">
                        <el-badge class="item" :value="chat.unRead" :max="99" :hidden="chat.unRead <= 0">
                          <el-avatar :src="chat.icon"></el-avatar>
                        </el-badge>
                      </el-col>
                      <el-col :span="8">
                        <span>{{chat.name}}</span>
                      </el-col>
                      <el-col :span="8">
                        <span class="el-icon-circle-close" style="cursor:pointer;"
                          @click.stop="removeUserChat(chat.id)"></span>
                      </el-col>
                    </el-row>
                  </li>
                </el-scrollbar>

              </template>
            </el-main>
            <el-footer>
              <el-row :gutter="20">
                <el-col :span="8">
                  <el-button icon="el-icon-circle-plus" circle @click="addUser = true"></el-button>
                </el-col>
                <el-col :span="8">
                  <el-button icon="el-icon-star-on" circle></el-button>
                </el-col>
                <el-col :span="8">
                  <el-button icon="el-icon-circle-close" circle @click="logout"></el-button>
                </el-col>
              </el-row>
            </el-footer>
          </el-container>
        </el-aside>

        <template v-if="teahouseId == null">
          <el-container>
            <el-main>
              <el-empty image="image/teapot.png" description="-_-" :image-size="300" style="opacity: 0.25;"></el-empty>
            </el-main>
          </el-container>
        </template>
        <transition name="el-fade-in">
          <template v-if="teahouseId != null">
            <el-container style="border-left: 1px solid #9b9191;">
              <el-main style="height:0;flex-grow:1;">
                <ul class="chat-main" ref="chatArea">
                  <li v-for="chat in chatList" class="infinite-list-item">
                    <!-- Left -->
                    <div v-if="chat.senderId != mine.id" class="chat-sender">
                      <div><img :src="teahouseIcon"></div>
                      <div>{{chat.senderId}}</div>
                      <div>
                        <div class="chat-left_triangle"></div>
                        <span class="messageText" v-if="chat.type == 1">{{chat.src}}</span>
                        <template v-if="chat.type == 2">
                          <video v-if='chat.fileType == "video"' :src="chat.src" style="max-width: 200px;"
                            controls></video>
                          <el-image v-else :src="chat.src" style="max-width: 200px;margin: 0px;max-height: 150px;"
                            :preview-src-list="[chat.src]" @error="chat.fileType='video';console.log(chat.fileType)">
                          </el-image>
                        </template>
                      </div>
                    </div>
                    <!-- Right -->
                    <div v-if="chat.senderId == mine.id" class="chat-receiver">
                      <div><img :src="mine.icon"></div>
                      <div style="display:none;">好人·马克思</div>
                      <div>
                        <div class="chat-right_triangle"></div>
                        <span class="messageText" v-if="chat.type == 1">{{chat.src}}</span>
                        <template v-if="chat.type == 2">
                          <video v-if='chat.fileType == "video"' :src="chat.src" style="max-width: 200px;"
                            controls></video>
                          <el-image v-else :src="chat.src" style="max-width: 200px;margin: 0px;max-height: 150px;"
                            :preview-src-list="[chat.src]" @error="chat.fileType='video';console.log(chat.fileType)">
                          </el-image>
                        </template>
                      </div>
                    </div>
                    <!-- Notice/Center -->
                    <div v-if="chat.origin == 1" class="chat-notice">
                      <span>你被群主移除群聊</span>
                    </div>
                  </li>
                </ul>
              </el-main>

              <el-footer :height="foot_height">
                <el-row :gutter="20">
                  <el-col :span="21">
                    <el-input v-model="send_input" style="height:96%" ref="chatInput" @keyup.enter.native="sendText"
                      clearable>
                      <i slot="suffix" class="el-icon-grape" @click="emojiDrawerVisible=true"></i>
                    </el-input>
                  </el-col>
                  <el-col :span="1">
                    <el-button icon="el-icon-star-off" type="primary" size="medium" circle @click="clickDrawer">
                    </el-button>
                  </el-col>
                  <el-col :span="2">
                    <el-button type="primary" @click="sendText">发送</el-button>
                  </el-col>
                </el-row>

                <el-row>
                  <el-row :gutter="20">
                    <el-col :span='4'>
                      <el-card shadow="hover" :body-style="{'line-height': '0px'}">
                        <el-upload class="upload-demo" action="uploadImage" :before-upload="beforeImageUpload"
                          :data="imageUploadData" :on-success="onImageUploaded" name="file" :show-file-list="false">
                          <el-image src="image/picture.png"></el-image>
                        </el-upload>
                      </el-card>
                    </el-col>
                    <el-col :span='4'>
                      <el-card shadow="hover" :body-style="{'line-height': '0px'}">
                        <el-image src="image/distribute.png" style="cursor:pointer;"></el-image>
                      </el-card>
                    </el-col>
                  </el-row>
                </el-row>
              </el-footer>
              <el-drawer :visible.sync="emojiDrawerVisible" direction="btt" :with-header="false" size="40%">
                <div class="emojiList">
                  <a v-for="item in emojiList" class="emojiItem" @click="clickEmoji(item)">{{item.char}}</a>
                </div>
              </el-drawer>
            </el-container>
          </template>
        </transition>
      </el-container>
    </el-container>

    <el-dialog title="添加用户" :visible.sync="addUser" width="30%" :show-close="false">
      <el-input v-model="addPageUserId" placeholder="请输入userId"></el-input>
      <span slot="footer" class="dialog-footer">
        <el-button @click="addUser = false">取 消</el-button>
        <el-button type="primary" @click="addUserChat(addPageUserId);addPageUserId = '';addUser = false;">确 定
        </el-button>
      </span>
    </el-dialog>
  </div>
</body>

<script src="js/vue.js"></script>
<script src="js/index.js"></script>
<script src="js/axios.min.js"></script>
<script>
  var app = new Vue({
    el: '#app',
    data: function () {
      return {
        console: console,
        teahouseName: '',
        teahouseId: null,
        teahouseIcon: '',
        addUser: false,
        chatGroup: [],
        chatList: [],
        send_input: '',
        emojiList: [],
        images: [],
        mine: {
          id: null,
          name: null,
          icon: null
        },
        websocket: {},
        addPageUserId: '',
        foot_height: "60px",
        emojiDrawerVisible: false,
        imageUploadData: {
          apiType: 'sina,bilibili,baidu',
          token: 'cd31d73edc8e6156bbfbdf610eb60480'
        }
      }
    },
    created: function () {
      axios.get('json/emoji.json').then(d => {
        this.emojiList = d.data
      })
    },
    mounted: function () {
      // 检查是否滑动
      setInterval(() => {
        if (this.$refs.chatArea == null) {
          return
        }

        let p_padding_top = document.defaultView.getComputedStyle(this.$refs.chatArea.parentElement).paddingTop
        p_padding_top = parseFloat(p_padding_top.replaceAll('px', ''))
        let margin_top = document.defaultView.getComputedStyle(this.$refs.chatArea).marginTop
        margin_top = parseFloat(margin_top.replaceAll('px', ''))
        let topJianGe = p_padding_top + margin_top // dom和父dom的间隔
        let realJianGeTop = this.$refs.chatArea.getBoundingClientRect().top - this.$refs.chatArea.parentElement.getBoundingClientRect().top
        if (realJianGeTop - topJianGe > -1) {
          // 划到最上方
        }

        let p_padding_bottom = document.defaultView.getComputedStyle(this.$refs.chatArea.parentElement).paddingBottom
        p_padding_bottom = parseFloat(p_padding_bottom.replaceAll('px', ''))
        let margin_bottom = document.defaultView.getComputedStyle(this.$refs.chatArea).marginBottom
        margin_bottom = parseFloat(margin_bottom.replaceAll('px', ''))
        let bottomJianGe = p_padding_bottom + margin_bottom // dom和父dom的间隔
        let realJianGeBottom = this.$refs.chatArea.getBoundingClientRect().bottom - this.$refs.chatArea.parentElement.getBoundingClientRect().bottom
        if (realJianGeBottom + bottomJianGe < 1) {
          // 划到最下方
        }
      }, 500)
    },
    methods: {
      selectToChat: function (chat) {
        this.teahouseId = chat.id
        this.teahouseName = chat.name
        this.teahouseIcon = chat.icon
        this.chatList = chat.chatList
        chat.unRead = 0

        // 点击的聊天
        let chatGroupShadow = []
        chatGroupShadow.push(chat)
        for (let i = 0; i < this.chatGroup.length; i++) {
          if (this.chatGroup[i].id != chat.id) {
            chatGroupShadow.push(this.chatGroup[i])
          }
        }
        this.chatGroup = chatGroupShadow
      },
      addUserChat: function (addPageUserId) {
        // 校验
        if (addPageUserId == null || addPageUserId.length == 0 || addPageUserId == this.mine.id) {
          this.$message.error('输入的id不合法')
          return
        }

        for (let i = 0; i < this.chatGroup.length; i++) {
          if (this.chatGroup[i].id == addPageUserId) {
            this.$message.error('输入的id已存在')
            return
          }
        }

        let userId = parseInt(addPageUserId)
        let chatGroupItem = {
          id: userId,
          name: userId,
          icon: "http://q1.qlogo.cn/g?b=qq&nk=" + userId + "&s=640",
          chatList: [],
          // vue使用
          unRead: 0
        }
        this.chatGroup.push(chatGroupItem)

        saveToLocalStorage()
        return chatGroupItem
      },
      removeUserChat: function (id) {
        let index = -1
        for (let i = 0; i < this.chatGroup.length; i++) {
          if (this.chatGroup[i].id == id) {
            index = i
            break
          }
        }

        if (index != -1) {
          let chatGroup = this.chatGroup.slice(0, index).concat(this.chatGroup.splice(index + 1))
          this.chatGroup = chatGroup

          // 删除正在打开的回话
          if (id == this.teahouseId) {
            this.teahouseId = null
            this.teahouseName = null
            this.chatList = []
          }
        }

        saveToLocalStorage()
      },
      sendText: function () {
        if (this.send_input.trim().length == 0) {
          this.$message.info('消息长度应该大于0')
          return
        }

        axios.post('sendMessage', {
          origin: 2, // 1-系统发送，2-用户发送
          type: 1, // 1-文本，2-图片
          senderId: app.mine.id,
          senderName: app.mine.id,
          receiverId: this.teahouseId,
          receiverName: this.teahouseName,
          src: this.send_input.trim()
        })
          .then(d => {
            saveToLocalStorage()
          })
        this.send_input = ''
      },
      clickDrawer: function () {
        if (this.foot_height != '260px') {
          this.foot_height = '260px'
        } else {
          this.foot_height = '60px'
        }
      },
      clickEmoji: function (emoji) {
        let input = this.$refs.chatInput.getInput()
        this.send_input = this.send_input.substring(0, input.selectionStart) + emoji.char + this.send_input.substring(input.selectionEnd)
        this.emojiDrawerVisible = false
      },
      logout: function () {
        setCookie('userId', '', -1)
        window.location.href = 'login.html'
        clearLocalStorage()
      },
      onImageUploaded: function (d) {
        // 关闭图片上传框
        this.foot_height = '60px'
        axios.post('sendMessage', {
          origin: 2, // 1-系统发送，2-用户发送
          type: 2, // 1-文本，2-图片
          senderId: app.mine.id,
          senderName: app.mine.id,
          receiverId: this.teahouseId,
          receiverName: this.teahouseName,
          src: d
        })
      },
      beforeImageUpload: function (file) {
        const isLt5M = file.size / 1024 / 1024 < 5;

        if (!isLt5M) {
          this.$message.error('上传媒体文件大小不能超过 5MB!');
        }
        return isLt5M;
      }
    }
  })

  // toLogin
  let userId = getCookie('userId')
  if (userId == null || userId.trim().length == 0) {
    window.location.href = 'login.html'
  }
  app.mine.id = userId
  app.mine.name = userId
  app.mine.icon = "http://q1.qlogo.cn/g?b=qq&nk=" + userId + "&s=640"

  // 加载上次的列表
  app.chatGroup = loadFromLocalStorage(app.mine.id)

  // websocket
  function getWebSocketPath() {
    let pathName = window.location.pathname
    let host = window.location.host

    return 'ws://' + host + pathName.slice(0, pathName.lastIndexOf('/')) + '/websocket'
  }

  function initWebSocket(socket) {
    app.websocket = socket

    socket.onopen = function () {
      app.$notify.success({
        title: '成功',
        message: '连接服务器',
      })
    }

    socket.onmessage = function (msg) {
      let chatItem = JSON.parse(msg.data)

      let chatGroupItem = null
      for (let i = 0; i < app.chatGroup.length; i++) {
        if (app.chatGroup[i].id == chatItem.receiverId || app.chatGroup[i].id == chatItem.senderId) {
          chatGroupItem = app.chatGroup[i]
        }
      }

      if (chatGroupItem == null) {
        // 未找到对话 1-两个人之间的聊天，使用senderId, 2-群组之间的聊天，使用receiverId
        if (chatItem.receiverId == app.mine.id) {
          // 别人发给你的
          chatGroupItem = app.addUserChat(chatItem.senderId)
        } else {
          // 别人发给群组的
          chatGroupItem = app.addUserChat(chatItem.receiverId)
        }
      }

      // 未读消息
      chatItem.fileType = 'image'
      chatGroupItem.chatList.push(chatItem)

      // 保存用户列表
      saveToLocalStorage()

      // 当前打开的聊天,未读消息清零
      if (chatItem.receiverId == app.teahouseId || chatItem.senderId == app.teahouseId) {
        chatGroupItem.unRead = 0
      } else {
        chatGroupItem.unRead += 1
      }
    }

    socket.onclose = function () {
      app.$notify.error({
        title: '断开',
        message: '与服务器断开连接',
      })

      setTimeout(() => {
        initWebSocket(new WebSocket(socket.url))
      }, 3 * 1000 + (Math.random() * 6000))
    }

    socket.onerror = function () {
      // app.$notify.error({
      //   title: '错误',
      //   message: '发生错误',
      // })
    }
  }
  initWebSocket(new WebSocket(getWebSocketPath() + '/' + app.mine.id))

  function setCookie(key, value, t) {
    var oDate = new Date();
    oDate.setDate(oDate.getDate() + t);
    document.cookie = key + "=" + value + "; expires=" + oDate.toDateString();
  }

  function getCookie(cname) {
    var name = cname + "=";
    var ca = document.cookie.split(';');
    for (var i = 0; i < ca.length; i++) {
      var c = ca[i].trim();
      if (c.indexOf(name) == 0) return c.substring(name.length, c.length);
    }
    return "";
  }

  function saveToLocalStorage() {
    let chatGroupString = JSON.stringify(app.chatGroup)

    // 保存最后10条消息
    let tChatGroup = JSON.parse(chatGroupString)
    tChatGroup.forEach(i => {
      i.chatList = i.chatList.slice(-10)
    })
    chatGroupString = JSON.stringify(tChatGroup)

    localStorage.setItem(app.mine.id + ".chatGroupString", chatGroupString)
  }

  function loadFromLocalStorage(id) {
    let chatGroupString = localStorage.getItem(id + ".chatGroupString")
    let r = JSON.parse(chatGroupString)
    if (r == null) {
      r = []
    }
    return r
  }

  function clearLocalStorage() {
    localStorage.clear()
  }
</script>

</html>